1 00:00:01,890 --> 00:00:07,080 Now that we have our animation created and we have an animation instance in our tool, it's time to 2 00:00:07,080 --> 00:00:10,200 load this animation onto our humanoid from our local script. 3 00:00:10,350 --> 00:00:15,750 We can load animations from the server as well, but I find it to be more optimal to load animations 4 00:00:15,750 --> 00:00:19,650 that will be run on a player's character from that player's client sided scripts. 5 00:00:19,830 --> 00:00:25,170 This is because, like I mentioned in a previous lecture, the movement of limbs of a player are one 6 00:00:25,170 --> 00:00:30,180 of the sole exceptions of things that are replicated directly from the client to the server and to the 7 00:00:30,180 --> 00:00:31,350 rest of the clients. 8 00:00:31,380 --> 00:00:36,420 That means if I run an animation from a local script on my character, everyone else will be able to 9 00:00:36,420 --> 00:00:36,930 see it. 10 00:00:37,470 --> 00:00:41,460 So in my local script, let's create a variable called anim. 11 00:00:43,760 --> 00:00:46,640 And get a reference to the eating animation in my tool. 12 00:00:48,510 --> 00:00:51,690 Next, I want to create a variable that stores my character. 13 00:00:51,690 --> 00:00:58,470 And so I'll call this variable character and set it equal to player, character or player character 14 00:00:58,470 --> 00:00:59,130 added. 15 00:01:00,340 --> 00:01:01,000 Cohen. 16 00:01:01,000 --> 00:01:01,840 Wait. 17 00:01:02,740 --> 00:01:03,790 What am I doing here? 18 00:01:03,820 --> 00:01:09,520 Well, the players character property may not have a model reference to it yet, as games may delay 19 00:01:09,520 --> 00:01:14,380 the player's character from spawning or simply waiting for the player's character model to replicate. 20 00:01:14,410 --> 00:01:18,880 In this instance, player character may return nil because it doesn't exist yet. 21 00:01:19,150 --> 00:01:24,970 So we use the or operator here and wait for the character added event to fire and this event returns 22 00:01:24,970 --> 00:01:26,080 the player's character. 23 00:01:26,080 --> 00:01:31,390 So any time that player character is nil, our script will default to this event and wait for it to 24 00:01:31,390 --> 00:01:32,080 fire. 25 00:01:33,060 --> 00:01:36,640 The next thing I want to do here is get a reference to my character's humanoid. 26 00:01:36,660 --> 00:01:38,850 So I'll create a variable called humanoid. 27 00:01:39,800 --> 00:01:43,130 And now listen up, because what I'm about to tell you is very important. 28 00:01:43,250 --> 00:01:48,530 When we join our game, we will have local scripts that get run immediately, meaning that they are 29 00:01:48,530 --> 00:01:53,480 local scripts that exist in starter player scripts or in the starter UI or in tools that are in the 30 00:01:53,480 --> 00:01:54,380 starter pack. 31 00:01:54,380 --> 00:01:57,530 And when we join the game, they start executing. 32 00:01:57,680 --> 00:02:02,660 Now the problem with this is that if there are any references to things in the workspace and replicated 33 00:02:02,660 --> 00:02:09,200 storage wherever they may not have been replicated to our client yet because our client is still downloading 34 00:02:09,200 --> 00:02:10,490 all the assets. 35 00:02:10,490 --> 00:02:15,380 This means that any references to things that have not yet been downloaded will return nil, and that's 36 00:02:15,380 --> 00:02:16,430 a big problem. 37 00:02:16,820 --> 00:02:22,340 So to fix this, Roadblocks has a function that you can call when indexing an instance and it's called 38 00:02:22,340 --> 00:02:23,510 wait for child. 39 00:02:23,810 --> 00:02:29,210 What this function does is yields the script until the child has appeared, or if the child is already 40 00:02:29,210 --> 00:02:30,740 there, then it doesn't yield. 41 00:02:31,100 --> 00:02:36,350 So if this donut was placed in the starter pack and it immediately starts running, there is no guarantee 42 00:02:36,350 --> 00:02:38,570 that everything in the tool will have replicated yet. 43 00:02:38,570 --> 00:02:40,940 So that's when we should use wait for child. 44 00:02:40,970 --> 00:02:45,610 Any time you anticipate that an object may not have been replicated yet, use wait for child. 45 00:02:45,620 --> 00:02:47,940 Otherwise you don't ever need to use it. 46 00:02:47,960 --> 00:02:52,760 You should never use this in server scripts or in situations where you don't expect a child of an instance 47 00:02:52,760 --> 00:02:54,170 to not have been replicated yet. 48 00:02:54,380 --> 00:02:58,310 And the reason we don't use it in server scripts is because everything in the game has already been 49 00:02:58,310 --> 00:02:59,390 downloaded to the server. 50 00:02:59,390 --> 00:03:01,070 It doesn't have to wait for anything. 51 00:03:02,160 --> 00:03:07,470 So here where I reference my animation, I can actually replace the statement with weight for child. 52 00:03:07,590 --> 00:03:13,200 That way, just in case the animation has not yet been replicated to the client, it yields the script 53 00:03:13,200 --> 00:03:14,700 and waits for it to become downloaded. 54 00:03:16,190 --> 00:03:18,880 Now the next thing I need to do is create another variable. 55 00:03:18,890 --> 00:03:20,480 I'll call it animator. 56 00:03:21,600 --> 00:03:25,650 And this will store the animator, for instance, that is a child of the humanoid. 57 00:03:25,890 --> 00:03:31,230 This animator allows us to use animations onto our humanoid and returns a playable track that has been 58 00:03:31,230 --> 00:03:33,540 specifically loaded on a player's character. 59 00:03:33,780 --> 00:03:38,670 And since it's not guaranteed that the animator will have replicated, I will put wait for child here 60 00:03:38,670 --> 00:03:39,180 to. 61 00:03:40,140 --> 00:03:42,540 The last variable I need to make is called track. 62 00:03:43,580 --> 00:03:48,380 And we'll store the result from the function that belongs to the animator, which is the load animation 63 00:03:48,380 --> 00:03:49,100 function. 64 00:03:49,280 --> 00:03:53,810 This function requires one parameter and that needs to be our animation instance. 65 00:03:56,480 --> 00:03:57,140 OC. 66 00:03:57,140 --> 00:04:00,080 We are now ready to start playing this animation. 67 00:04:01,100 --> 00:04:05,270 Now, there's something else I'd like to mention here, and is that when we use this weight for child 68 00:04:05,270 --> 00:04:10,700 function and weight for the humanoid, the interpreter actually doesn't know what instance we're waiting 69 00:04:10,700 --> 00:04:11,330 for. 70 00:04:11,360 --> 00:04:17,480 That's why when I indexed Humanoid, it doesn't really show you any of the humanoid properties. 71 00:04:17,480 --> 00:04:20,990 It just shows you the generic properties that all instances have. 72 00:04:21,890 --> 00:04:25,880 So how do I let the game know that this function will return a humanoid? 73 00:04:25,880 --> 00:04:29,690 That way I can see all of the attributes that belong to a humanoid. 74 00:04:30,600 --> 00:04:36,810 Well, I can put two coins here, and then afterward I can declare the type that this variable should 75 00:04:36,810 --> 00:04:37,500 store. 76 00:04:37,500 --> 00:04:40,140 And that type is going to be a humanoid. 77 00:04:41,350 --> 00:04:47,860 Now when I index humanoid, I can see all the events that belong to the humanoid, like died jumping 78 00:04:47,860 --> 00:04:49,870 and all the other properties like health. 79 00:04:50,670 --> 00:04:53,250 I can also do the same for the animator. 80 00:04:53,880 --> 00:04:58,110 I can say that this variable will store a animator, for instance. 81 00:04:58,960 --> 00:05:03,640 And now if I index the animator, I can now see the load animation pop up where I didn't see it pop 82 00:05:03,640 --> 00:05:05,890 up earlier when I was trying to access it. 83 00:05:06,310 --> 00:05:12,160 One more thing is that since this animator type was previously unknown, the game won't know what the 84 00:05:12,220 --> 00:05:14,770 track variables referencing, but it should now. 85 00:05:14,860 --> 00:05:21,390 When I index it, you see all the properties for the track instance, such as stopped playing, ended 86 00:05:21,400 --> 00:05:22,510 all that good stuff. 87 00:05:24,170 --> 00:05:29,450 So moving on, let's implement this animation into my script and actually run the track so we can see 88 00:05:29,450 --> 00:05:31,040 our player eating our donut. 89 00:05:32,140 --> 00:05:37,420 So firstly, what I want to do is that when I activate this tool, I want to play the animation. 90 00:05:37,420 --> 00:05:42,670 So after I set the cool down to True or the bounce, I'm going to reference my track and then call the 91 00:05:42,670 --> 00:05:46,210 play function on it and it'll start playing my animation next. 92 00:05:46,210 --> 00:05:51,340 What I can do is I can reference my track again and get access to a function and it should be called 93 00:05:51,340 --> 00:05:58,120 get marker reach signal, and then I can pass in the string byte, which was the name of that animation 94 00:05:58,120 --> 00:05:59,900 event we put in our animation. 95 00:05:59,980 --> 00:06:05,800 So what this does is it returns the event that was at this bite marker, and that means I can connect 96 00:06:05,800 --> 00:06:07,060 a function to it. 97 00:06:08,360 --> 00:06:13,550 And inside this function, when the animation track reaches that byte point, then I can fire to the 98 00:06:13,550 --> 00:06:18,710 server to heal me and then I can yield for the cool down before I set the DB bounce back to false. 99 00:06:18,980 --> 00:06:24,080 Now the issue with this here is that if a player unequipped their tool while they're in the middle of 100 00:06:24,080 --> 00:06:27,660 an animation, it'll look like they're eating error and I don't want that. 101 00:06:27,770 --> 00:06:33,650 So what I can do is I can access an event in tool called Unequipped Connect a function to it. 102 00:06:34,700 --> 00:06:41,900 And here what I can do is I can reference my track and then I can stop it at any point when the player 103 00:06:41,910 --> 00:06:43,090 unequipped the tool. 104 00:06:43,100 --> 00:06:45,230 If the track hasn't been played, it's fine. 105 00:06:45,230 --> 00:06:46,250 This won't error. 106 00:06:47,240 --> 00:06:53,330 And then the next thing I can do is I can set the d bounce to false in here just in case. 107 00:06:53,330 --> 00:06:59,570 When I play this track, it doesn't reach the byte signal because it got stopped before then and I can 108 00:06:59,570 --> 00:07:04,130 still set the cool down to false, even though we were never able to override it and set it to false 109 00:07:04,130 --> 00:07:04,640 here. 110 00:07:05,330 --> 00:07:10,070 Now there's another big issue with this, if you haven't noticed yet, and that's when every time I 111 00:07:10,070 --> 00:07:16,310 click this tool, every time I activate it, I keep connecting a new function to this byte event. 112 00:07:16,310 --> 00:07:21,290 Every single time I click, I'm connecting another function, another function, another function, 113 00:07:21,290 --> 00:07:26,480 and eventually I'll connect so many functions that these few lines of code here will be running so many 114 00:07:26,480 --> 00:07:26,930 times. 115 00:07:26,930 --> 00:07:28,200 And I don't want that to happen. 116 00:07:28,220 --> 00:07:35,330 So what I can do instead, I can access the equipped event, connect a function to it. 117 00:07:35,990 --> 00:07:41,060 And in here, this is the only time I want to connect a function to the byte event. 118 00:07:41,060 --> 00:07:45,560 That way I don't keep connecting so many every time I click and activate the tool. 119 00:07:46,460 --> 00:07:53,420 And then what else I want to do is I want to store the return from this event, which is the function, 120 00:07:53,420 --> 00:08:00,020 I'll call it byte function or connected byte function. 121 00:08:00,410 --> 00:08:04,700 I won't assign it anything here, but I will assign it the return from here. 122 00:08:08,260 --> 00:08:14,740 And since I have it stored in a variable now, when I unequipped my tool, I can go and disconnect this 123 00:08:14,740 --> 00:08:15,330 event. 124 00:08:15,340 --> 00:08:18,010 I can disconnect the function from this event. 125 00:08:18,010 --> 00:08:23,080 That way we aren't building up so many functions that keep getting connected to these few lines of code 126 00:08:23,080 --> 00:08:23,560 here. 127 00:08:24,040 --> 00:08:29,950 So what this does, basically every time I equip my tool, I connect a function to this event. 128 00:08:30,100 --> 00:08:33,460 And then when I unequipped my tool, I disconnect that function. 129 00:08:33,460 --> 00:08:39,190 And this stops me from building up function after function to this event for me equipping my tool. 130 00:08:39,550 --> 00:08:43,990 So now if I run my game, I should be able to see my animation and then I get healed by it. 131 00:08:53,520 --> 00:08:55,200 Psych studios being a little weird. 132 00:08:56,770 --> 00:08:57,490 There we go. 133 00:08:58,900 --> 00:09:04,030 So if I damage myself a little bit and then grab my donut, if I eat it, I should see my animation. 134 00:09:04,390 --> 00:09:05,410 Perfect. 135 00:09:06,660 --> 00:09:09,600 And it's healing me and I can't spam click it either. 136 00:09:10,870 --> 00:09:16,840 And if I equip it, re-equip it to do that a bunch of times to see whether or not it's building up a 137 00:09:16,840 --> 00:09:20,110 bunch of functions to that event, that animation event. 138 00:09:20,900 --> 00:09:22,670 And let me damage myself a little bit more. 139 00:09:23,690 --> 00:09:26,030 And it's still only healing me by five. 140 00:09:26,270 --> 00:09:32,180 That means that the clicked event isn't being fired more than once each time I bite on my donut. 141 00:09:33,290 --> 00:09:35,190 Now, the last thing I want to do is I want to play a sound. 142 00:09:35,210 --> 00:09:36,500 My donut gets eaten. 143 00:09:36,800 --> 00:09:40,190 And in order for everyone to hear that, I have to do it on the server. 144 00:09:40,190 --> 00:09:44,480 Because if I try to play a sound on the client, only that client will be able to hear it. 145 00:09:45,190 --> 00:09:46,810 So let's find a sound. 146 00:09:46,810 --> 00:09:51,550 Actually, let's go to the toolbox and let's go to the marketplace. 147 00:09:51,550 --> 00:09:54,580 We can go to sounds or audio. 148 00:09:55,890 --> 00:09:58,170 And then let's just search for, like, bite. 149 00:09:59,430 --> 00:10:00,390 Okay, that didn't work. 150 00:10:00,390 --> 00:10:02,970 Let's search for it. 151 00:10:07,080 --> 00:10:07,680 Um. 152 00:10:11,360 --> 00:10:11,660 Sure. 153 00:10:11,660 --> 00:10:15,020 Yeah, this one will work so we can insert it here into our tool. 154 00:10:16,520 --> 00:10:18,260 I'll just rename it to eat. 155 00:10:19,200 --> 00:10:20,670 And then here my server script. 156 00:10:20,670 --> 00:10:22,050 I'll create a reference to it. 157 00:10:22,530 --> 00:10:24,300 I'll just call it sound. 158 00:10:25,470 --> 00:10:28,440 I'll do script start Parent dot eat. 159 00:10:29,590 --> 00:10:33,670 And then when they player clicks, I will just play this sound. 160 00:10:35,400 --> 00:10:37,590 If I go back into my game and I run again. 161 00:10:41,340 --> 00:10:42,330 Every time I eat my donut. 162 00:10:42,330 --> 00:10:45,480 It should play the sound perfect. 163 00:10:51,050 --> 00:10:55,850 Now, one more thing is that in the sound property, there's a couple of properties in here that tell 164 00:10:55,850 --> 00:10:57,980 you how far away the sound can be heard. 165 00:10:58,370 --> 00:11:00,920 So right now it's set to 10,000 studs. 166 00:11:00,920 --> 00:11:05,750 So that means anyone, 10,000 studs away can actually hear the sound, which is way too far. 167 00:11:05,780 --> 00:11:08,150 I'll set it to something more modest, like 35. 168 00:11:08,630 --> 00:11:11,330 And then this other integer here tells me the distance. 169 00:11:11,330 --> 00:11:15,830 I want the sound to start becoming more quiet, basically. 170 00:11:15,830 --> 00:11:18,490 And they have a couple of modes here that I can do that with. 171 00:11:18,500 --> 00:11:25,040 I'll try tapered so that way, as I get further and further away from Ted Studs, once I reached 35 172 00:11:25,040 --> 00:11:29,860 studs, the sound is completely silent and when I reach 34 it gets slightly louder. 173 00:11:29,870 --> 00:11:33,440 35 or I mean 33, slightly more louder. 174 00:11:33,440 --> 00:11:37,520 Until you reach ten, it reaches the loudest and it doesn't change. 175 00:11:37,520 --> 00:11:41,450 So from 0 to 10 studs away from the donat, the sound will be the same volume. 176 00:11:41,450 --> 00:11:45,890 But once you get greater than ten studs away, then it will become quieter and quieter until it becomes 177 00:11:45,890 --> 00:11:48,230 completely quiet at 35 studs. 178 00:11:49,460 --> 00:11:51,020 So let's try it again here. 179 00:11:54,860 --> 00:11:56,780 And if I put my camera super far away, 180 00:12:00,200 --> 00:12:01,280 it's still kind of here. 181 00:12:01,280 --> 00:12:01,640 It. 182 00:12:08,000 --> 00:12:08,650 Oh, you know what? 183 00:12:08,660 --> 00:12:11,210 I know exactly why it's acting a fool. 184 00:12:11,240 --> 00:12:14,570 It's because I have to actually parent the sound to a part. 185 00:12:14,600 --> 00:12:19,310 That way, the sound radiates from the part, because otherwise, the game thinks that the sound belongs 186 00:12:19,310 --> 00:12:20,780 to the entire workspace. 187 00:12:20,780 --> 00:12:23,390 So it's playing the sound for everyone everywhere. 188 00:12:23,390 --> 00:12:24,980 And it's not decreasing the volume. 189 00:12:25,910 --> 00:12:28,460 So let's fix that. 190 00:12:28,490 --> 00:12:30,080 I got to change the reference here. 191 00:12:30,260 --> 00:12:32,860 So I'll do handle Dot eat. 192 00:12:33,530 --> 00:12:34,760 And now it should work. 193 00:12:35,090 --> 00:12:37,220 Basically another logical error there. 194 00:12:37,820 --> 00:12:39,530 It wasn't acting the way I wanted. 195 00:12:42,250 --> 00:12:45,130 So I can't hear it from all the way over here if I zoom in closer. 196 00:12:45,160 --> 00:12:46,300 Still can't hear it. 197 00:12:47,530 --> 00:12:48,490 Still can't hear it. 198 00:12:49,690 --> 00:12:53,440 You can kind of hear it and I can fully hear it. 199 00:12:58,070 --> 00:12:58,940 Perfect. 200 00:13:00,300 --> 00:13:03,960 You might notice that we're holding this doughnut a little funny, and I actually show you how to change 201 00:13:03,960 --> 00:13:04,800 that real quick. 202 00:13:05,340 --> 00:13:09,360 If I go into my character model here, here I am. 203 00:13:09,360 --> 00:13:10,590 Find my donut. 204 00:13:11,420 --> 00:13:13,430 I can actually change the positioning of it. 205 00:13:13,430 --> 00:13:19,250 So if I change it, like here, actually it's not moving. 206 00:13:19,340 --> 00:13:20,330 Why is it a moving? 207 00:13:23,640 --> 00:13:25,950 Oh, I have to unequipped it and re-equip it. 208 00:13:26,670 --> 00:13:27,300 Can actually see. 209 00:13:27,300 --> 00:13:32,220 I can move it around to a position I find better. 210 00:13:36,730 --> 00:13:38,920 So maybe I wanted to hold it out a little bit further. 211 00:13:47,070 --> 00:13:49,440 Maybe I want to hold it probably at 0.3. 212 00:13:50,390 --> 00:13:51,980 And then maybe a little bit more to the right. 213 00:13:51,980 --> 00:13:52,970 So I'll do point. 214 00:13:53,770 --> 00:13:56,590 Two or maybe just 0.1. 215 00:14:03,530 --> 00:14:03,890 There we go. 216 00:14:03,890 --> 00:14:07,310 Now I'm holding my donut a little bit nicer so I can actually copy these numbers. 217 00:14:09,490 --> 00:14:15,250 And in that position property, I can update it here so when I go and grab my donut. 218 00:14:18,410 --> 00:14:20,420 It's sitting in my hand a little more nicely. 219 00:14:22,520 --> 00:14:23,600 Okay, one more thing. 220 00:14:23,600 --> 00:14:24,560 I promise. 221 00:14:24,740 --> 00:14:28,340 If you want to change the name of the donut, just rename the tool. 222 00:14:28,430 --> 00:14:32,300 I'll just name it to Blue Frosted Donut. 223 00:14:32,780 --> 00:14:34,490 And that way, when I play my game. 224 00:14:36,250 --> 00:14:37,420 And I got to pick it up. 225 00:14:38,500 --> 00:14:39,640 You see the name right here? 226 00:14:39,640 --> 00:14:40,930 Blue Frosted Doughnut. 227 00:14:44,790 --> 00:14:48,760 Okay, so that's how you create a healing donut and robotics. 228 00:14:48,760 --> 00:14:52,030 In the next lecture, we have another fun activity to complete.